/*!
 * \file cicsts_core.h
 *
 * \brief CICSTS模块主文件
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.
 *
 * \version 1.0
 * \author songbb
 * \date 2016/04/22
 *
 */

#ifndef __CICSTS_CORE_H_
#define __CICSTS_CORE_H_

#include "frlist.h"
#include "frhash2.h"
#include "frstr.h"

#include "conntrack.h"
#include "module.h"
#include "frbyte_buffer.h"

/*! @brief CICSTS协议通用包头 */
typedef struct __st_cicsts_header
{
    unsigned int ui_msg_id;              /*!< MessageID */
    unsigned int ui_header_len;          /*!< 消息头长度 */
    unsigned int ui_pkt_len;             /*!< 消息体长度 */
} CicsTS_header;

/*! @brief 分片的状态 */
typedef enum __em_fragment_state {
    APM_CICSTS_FRAGMENT_INIT,                     //!< 初始化
    APM_CICSTS_FRAGMENT_NEED_NEXT_REQ_PACKET,     //!< 需要下一个请求包
    APM_CICSTS_FRAGMENT_NEED_NEXT_RESP_PACKET     //!< 需要下一个响应包
} CicsTS_fragment_state;

/*! @brief CICSTS数据包 */
typedef struct __st_L7_cicsts_packet
{
    CicsTS_fragment_state fragment_state; //!< 当前的分片状态
    Frbyte_Packet *p_st_packet;         //!< 组包完成的数据
    unsigned int ui_header_len;         //!< Header长度
    unsigned int ui_length;             //!< 数据包长度
    unsigned int ui_len_to_read;        //!< 还需要从下一个payload中读取多少个字节
    struct timeval st_timestamp_first;  //!< 第一个请求的分片包的时间
    struct timeval st_timestamp_last;   //!< 最后一个请求的分片包的时间
    unsigned long ul_skip_len;          //!< 需要跳过的长度
    unsigned int ui_msg_id;             //!< MessageID
} L7_cicsts_packet;

/*! @brief CICSTS交易信息 */
typedef struct __st_L7_cicsts_stmt
{
    struct timeval st_req_end_timestamp;    //!< 请求的结束时间戳
    struct timeval st_resp_start_timestamp; //!< 响应的开始时间戳
    unsigned long ul_resp_server_time_us;   //!< 响应的Server时间

    unsigned int ui_msg_id;                 //!< MessageID
    Frlist_header *p_report_comm;          //!< 用于临时存储report的公共部分数据
    Frlist_header *p_report_req;           //!< 用于临时存储report的请求部分数据
} L7_cicsts_stmt;

/*! @brief CICSTS私有结构体 */
typedef struct __st_L7session_cicsts_private
{
    Frhash_header *p_hash_stmt;            //!< 按message_id建立hash
    L7_cicsts_packet *p_st_cicsts_packet;  //!< 当前处理中的CicsTS数据包
    L7_session *p_st_session;              //!< 指向父级的L7_session结构体
} L7session_cicsts_private;

/*!
 * 判断当前数据链路是否是CICSTS协议的
 *
 * \param p_st_conn        (ct信息)
 * \param p_st_packet     (协议分析入力数据)
 *
 * \return 参照module.h中APM_L7_IS_的定义
 *
 */
int cicsts_detect(Conntrack *p_st_conn
            , Apm_packet *p_st_packet);

/*!
 * CICSTS协议解析入口
 *
 * \param p_st_conn             (ct信息)
 * \param p_st_packet          (协议分析入力数据)
 * \param p_st_hash_report      (保存Frreport_data)
 *
 * \return 参照module.h中APM_L7_ANALYZE_的定义
 *
 */
int cicsts_analyze(Conntrack *p_st_conn
                , Apm_packet *p_st_packet
                , Frhash_header *p_st_hash_report);

/*!
 * 释放CICSTS private数据
 *
 * \param p_st_session_private_in        (CICSTS的私有信息)
 *
 * \return 0  失败\n
 *         1  成功
 *
 */
int cicsts_session_destory(void *p_st_session_private_in);

#endif
